package com.baichang.taoshunda.service.impl;

import com.baichang.framework.Code;
import com.baichang.framework.Constant;
import com.baichang.framework.excelption.ServiceException;
import com.baichang.framework.model.Page;
import com.baichang.framework.utils.AES;
import com.baichang.framework.utils.MD5Util;
import com.baichang.framework.utils.TokenUtils;
import com.baichang.framework.utils.http.HttpUtils;
import com.baichang.sms.utils.SMSUtils;
import com.baichang.taoshunda.SMSConstants;
import com.baichang.taoshunda.dao.*;
import com.baichang.taoshunda.entity.Pension;
import com.baichang.taoshunda.entity.User;
import com.baichang.taoshunda.service.*;
import com.baichang.taoshunda.utils.ConvertTypeUtils;
import com.baichang.taoshunda.utils.EasemobContants;
import com.baichang.taoshunda.utils.RongYunUtils;
import net.sf.json.JSONObject;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * Created by Administrator on 2017/8/17 0017.
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;
    @Autowired
    private ParamsService paramsService;
    @Autowired
    private ScoreService scoreService;
    @Autowired
    private ScoreListService scoreListService;
    @Autowired
    private MsgService msgService;
    @Autowired
    private ScoreDao scoreDao;
    @Autowired
    private TrendsUserService trendsUserService;

    @Autowired
    private BussinessDao bussinessDao;

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private BalanceDetailsDao balanceDetailsDao;

    @Autowired
    private DeliveryClerkDao deliveryClerkDao;
    @Autowired
    private RyFriendService ryFriendService;

    @Autowired
    private TrendService trendService;

    @Autowired
    private PensionDao pensionDao;

    @Autowired
    private RebateDao rebateDao;

    /**
     * @param nowPage
     * @param pageSize
     * @param nickName
     * @param startCreated
     * @param endCreate    @return
     * @param startTime
     * @param endTime
     */
    @Override
    public Page queryUserList(int nowPage, int pageSize, String nickName, String startCreated, String endCreate, String startTime, String endTime) {
        return userDao.queryUserList(nowPage, pageSize, nickName, startCreated, endCreate, startTime, endTime);
    }

    /**
     * 查询用户订单表
     *
     * @param id
     * @param nowPage
     * @param pageSize @return
     */
    @Override
    public Page queryOrderList(Integer id, int nowPage, int pageSize) {
        return orderDao.queryOrderList(id, nowPage, pageSize);
    }

    /**
     * 查询收支明细
     *
     * @param id
     * @param nowPage
     * @param pageSize
     * @return
     */
    @Override
    public Page queryMoneyDetails(Integer id, int nowPage, int pageSize) {
        return balanceDetailsDao.queryMoneyDetails(id, nowPage, pageSize);
    }

    /**
     * 修改用户信息
     *
     * @param account
     * @param nickName
     * @param headPic
     * @param id
     * @return
     */
    @Override
    public int updateUserInfo(String account, String nickName, String headPic, Integer id) {
        Map map = new HashedMap();
        map.put("account", account);
        map.put("nickName", nickName);
        map.put("headPic", headPic);
        return userDao.update(map, id);
    }

    /**
     * 重置密码
     *
     * @param id
     * @param pwd
     * @return
     */
    @Override
    public int resetPassword(Integer id, String pwd) {
        String pass = MD5Util.md5(pwd);
        return userDao.updatePassWord(id, pass);
    }

    /**
     * 修改用户状态
     *
     * @param id
     * @param state
     * @return
     */
    @Override
    public int updateUserState(Integer id, Integer state) throws ServiceException {
        if (state == 0 || state == 2) {
            List<Map<String, Object>> status = orderDao.getOrderByUserInfo(id);
            for (int i = 0; i < status.size(); i++) {
                int s = Integer.parseInt(status.get(i).get("orderState").toString());
                if (state == 0) {
                    if (s == 7) {
                        throw new ServiceException("该用户有处于申请退款的订单，不能删除");
                    }
                } else {
                    if (s == 7) {
                        throw new ServiceException("该用户有处于申请退款的订单，不能禁用");
                    }
                }
            }
        }
        return userDao.updateUserState(id, state);
    }

    /**
     * 普通用户注册
     *
     * @param phone 手机号
     * @param pwd   账号
     * @param code  验证码
     * @return
     */
    @Override
    public Map<String, Object> registerConsumer(String phone, String pwd, String code) throws ServiceException {
        //声明变量接收返回值
        Map<String, Object> map = new HashMap<String, Object>(1);
        //判断验证码   msgService.checkRegisterCode(phone, code)
        if (true) {
            //判断是否存在
            User user = userDao.getUserByUserName(phone);
            if (user != null) {
                throw new ServiceException("该手机号已被注册");
            }
            user = new User();
            user.setCreated(new Date());
            user.setAccount(phone);
            user.setPwd(MD5Util.md5(pwd));
            user.setHeadPic("");
            //设置用户状态
            user.setUserState(1);
            //最后登录时间
            user.setLastTime(new Date());
            user.setSex("");
            user.setRedPacket(BigDecimal.valueOf(0));
            //昵称
            String str = "****";
            StringBuilder sb = new StringBuilder(phone);
            sb.replace(3, 7, str);
            user.setNickName("用户_" + sb.toString());
            user.setBackgroundImage("");
            user.setIsCertification(0);
            user.setIsCertificate(0);
            user.setInviteAccount("");
            user.setHandheldPhotos("");
            user.setCardId("");
            user.setCardName("");
            user.setRebateAmount(BigDecimal.valueOf(0));
            user.setFontCard("");
            user.setReverseCard("");
            //接收用户编号
            Integer userId = (int) userDao.save(user);
            //添加用户是否成功
            if (userId > 0) {
                int busId = 0;
                String flag = trendService.saveUser(phone, pwd, userId, sb.toString(), phone, "", 1);
                String hander = trendService.getToken(userId, 1).get("accessToken").toString();
                String trendsUserId = null;
                trendsUserService.addTrendsUser(userId, 0);
                try {
                    trendsUserId = trendService.getToken(userId, 1).get("uniqueId").toString();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (!Objects.equals(flag, "")) {
                    /**进行第一次积分的添加 1.获取参数设置的第一次积分的参数值*/
                    int paramsType = 2;
                    int paramsId = 3;
                    Map<String, Object> score = paramsService.getParamsValue(paramsType, paramsId);
                    //获取积分
                    int point = Integer.parseInt(score.get("value").toString());
                    //积分来源
                    String source = "首次下载注册获取积分";
                    //添加积分
                    if (scoreService.addScore(point, userId)) {
                        //添加积分详细
                        scoreListService.addScoreList(point, userId, source);
                        map.put("userId", userId);
                        String ryToken = RongYunUtils.getRYToken("user" + userId, phone, "");
                        userDao.updateRYToken(ryToken, userId, trendsUserId);
                        String token = TokenUtils.putValue(map, 30);
                        map.put("token", token);
                        map.put("hander", hander);
                        map.put("userName", phone);
                        map.put("trendsUserId", trendsUserId);
                        map.put("RyToken", JSONObject.fromObject(ryToken).get("token"));
                        map.put("RyUserId", JSONObject.fromObject(ryToken).get("userId"));
                        return map;
                    } else {
                        throw new ServiceException("注册失败，如有疑问请联系我们的客服");
                    }
                } else {
                    throw new ServiceException("网络繁忙请稍后再试");
                }
            } else {
                throw new ServiceException("网络繁忙请稍后再试");
            }
        } else {
            return map;
        }

    }

    /**
     * 请求接口
     *
     * @param actionUrl 请求的控制器地址
     * @param params    请求参数
     */
    private static Map<String, Object> executePost(String actionUrl, Map<String, Object> params) throws ServiceException {
        String url = EasemobContants.url;
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("action", actionUrl);
        jsonObject.put("params", params);
        String json = jsonObject.toString();
        String data = null;
        String result = null;
        try {
            //请求加密
            data = AES.encode(json, Constant.REQUEST_KEY);
            result = HttpUtils.postString(url, data);
            // 解密
            result = AES.decode(result, Constant.RESPONSE_KEY);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Map<String, Object> resultMap;
        try {
            resultMap = JSONObject.fromObject(result);
        } catch (Exception e) {
            resultMap = new HashMap<>(1);
        }
        Object resultObj = resultMap.get("res");
        if (resultObj == null) {
            throw new ServiceException(Code.code_error, "请求环信失败");
        }
        Map<String, Object> returnMap = (Map<String, Object>) resultObj;
        Integer returnCode = ConvertTypeUtils.obj2Integer(returnMap.get("code"));
        if (returnCode != 40000) {
            throw new ServiceException(Code.code_error, "请求环信失败");
        }
        return returnMap;
    }

    /**
     * 接口
     * 忘记密码
     * 1.判断用户名是否存在
     * 2.修改密码
     *
     * @param userName 用户名
     * @param pwd      密码
     * @return 修改成功/失败
     */
    @Override
    public boolean foreginPwd(String userName, String pwd) throws ServiceException {
        //根据用户名获取用户信息
        User user = userDao.getUserByUserName(userName);
        //1.判断用户是否存在
        //不存在提示信息
        if (user == null) {
            throw new ServiceException("账号不存在");
        }
        //修改密码
        return userDao.updateUserPwd(user.getId(), MD5Util.md5(pwd)) > 0;
    }

    /**
     * 接口
     * 获取用户个人信息
     *
     * @param userId 用户编号
     * @return 用户信息
     */
    @Override
    public Map<String, Object> getUserInfo(Integer userId) throws ServiceException {
        Map<String, Object> map = new HashMap<String, Object>(1);
        User user = userDao.getUserByUserId(userId);
        Pension pension = pensionDao.getPensionByUserId(userId);
        int score = scoreDao.getScoreByUserId(userId);
        if (user == null) {
            throw new ServiceException("用户不存在");
        }
        //头像
        map.put("headPic", user.getHeadPic());
        //名称
        map.put("name", user.getNickName());
        map.put("hxUser", user.getHxName());
        //账号
        map.put("account", user.getAccount());
        map.put("backgroundImage", user.getBackgroundImage());
        //积分
        map.put("score", score);
        map.put("isCertificate", user.getIsCertificate());
        if (pension != null) {
            map.put("pension", pension.getPension());
        } else {
            map.put("pension", 0);
        }
        map.put("isCertification", user.getIsCertification());
        map.put("sex", user.getSex());
        //编号
        map.put("id", user.getId());
        map.put("ryToken", user.getRyToken());
        return map;
    }


    /**
     * 接口
     * 判断用户密码
     *
     * @param userId 用户编号
     * @param pwd    用户密码
     * @return 密码成功/失败
     */
    @Override
    public boolean checkUserPwd(Integer userId, String pwd) throws ServiceException {
        User user = userDao.getUserByUserId(userId);
        if (user == null) {
            throw new ServiceException("用户不存在");
        }
        if (!MD5Util.md5(pwd).equals(user.getPwd())) {
            throw new ServiceException("密码不正确");
        }
        return true;
    }

    /**
     * 接口
     * 修改密码
     * 1.判断用户是否存在
     * 2.判断两次密码是否正确
     * 3.修改密码
     *
     * @param userId  用户编号
     * @param pwd     密码
     * @param surePwd 确认密码
     * @return
     */
    @Override
    public boolean updateUserPwd(Integer userId, String pwd, String surePwd) throws ServiceException {
        User user = userDao.getUserByUserId(userId);
        if (user == null) {
            throw new ServiceException("用户不存在");
        }
//        if (!pwd.equals(surePwd)) {
//            throw new ServiceException("两次密码不一致");
//        }
        trendService.updateInfo(userId, user.getAccount(), MD5Util.md5(pwd), user.getAccount(), 1, user.getNickName(), user.getHeadPic(), user.getSex());
        return userDao.updateUserPwd(userId, MD5Util.md5(pwd)) > 0;
    }

    /**
     * 接口
     * 修改个人信息
     *
     * @param id      用户编号
     * @param headPic 头像
     * @param name    名称
     * @param sex
     * @return 修改成功/失败
     */
    @Override
    public boolean updateUserInfo(Integer id, String headPic, String name, String hxKid, String sex) throws ServiceException {
        //检查用户信息
        Map<String, Object> userInfo = getUserInfo(id);
        User user = userDao.getUserByUserId(id);
//        if (!hxKid.equals("") || !hxKid.isEmpty()) {
//            EasemobUtils.update(hxKid, UserType.用户, name, headPic);
//        }
        String userId = JSONObject.fromObject(userInfo.get("ryToken").toString()).get("userId").toString();
        RongYunUtils.refreshInfo(userId, name, headPic);
//        int trendsUserId = trendsUserService.getTrendsUserIdByUserId(id);
        ryFriendService.updateHeadPic(userId, "http://www.taoshunda.com/images/" + headPic, sex, name);
//        trendsUserService.updateUserInfo(trendsUserId, name, headPic);
        trendService.updateInfo(id, user.getAccount(), user.getPwd(), user.getAccount(), 1, name, headPic, sex);
        return userDao.updateUserInfo(id, headPic, name, sex) > 0;
    }

    /**
     * 用户登录
     * 1.判断用户是否存在
     * 2.判断用户密码是否正确
     * 3.判断账号状态是否正常
     *
     * @param userName 账号
     * @param pwd      密码
     * @param type
     * @param code
     * @return
     */
    @Override
    public Map<String, Object> login(String userName, String pwd, int type, String code) throws ServiceException {
        Map<String, Object> map = new HashMap<String, Object>(1);
        //根据用户名获取用户信息
        User user = userDao.getUserByUserName(userName);
        //判断用户是否存在
        //不存在提示信息
        if (user == null) {
            throw new ServiceException("账号不存在");
        }

        if (type == 1) {
            //存在
            //判断账号密码是否正确
            String md5Pwd = MD5Util.md5(pwd);
            //密码不正确提示
            if (!user.getPwd().equals(md5Pwd)) {
                throw new ServiceException("密码不正确");
            }
        } else {
            msgService.checkForeignPwdCode(userName, code);
        }

        //密码正确检查用户状态
        if (user.getUserState() == 2) {
            throw new ServiceException("用户已被禁用");
        }
        String hander = trendService.getToken(user.getId(), 1).get("accessToken").toString();
        String trendsUserId = null;
        try {
            trendsUserId = trendService.getToken(user.getId(), 1).get("uniqueId").toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
//        int trendsUserId = trendsUserService.getTrendsUserIdByUserId(user.getId());
        int reminderTime = Integer.parseInt(paramsService.getParamsValue(30, 28).get("value").toString());
        //状态正常组装用户信息
        map.put("userId", user.getId());
        map.put("hxUser", user.getHxName());
        map.put("reminderTime", reminderTime);
        map.put("hxPwd", user.getHxPwd());
        map.put("userName", user.getNickName());
        map.put("backgroundImage", user.getBackgroundImage());
        map.put("trendsUserId", trendsUserId);
        map.put("uerName", userName);
        map.put("headPic", user.getHeadPic());
        map.put("RyToken", JSONObject.fromObject(user.getRyToken()).get("token"));
        map.put("RyUserId", JSONObject.fromObject(user.getRyToken()).get("userId"));
        String token = TokenUtils.putValue(map, 30);
        //修改最后登录时间
        map.put("token", token);
        map.put("hander", hander);
        userDao.updateUserLastTime(user.getId(), new Date());

        return map;
    }

    /**
     * 根据用户编号获取用户信息
     *
     * @param userId 用户编号
     * @return
     */
    @Override
    public User getUserBeanById(Integer userId) throws ServiceException {
        User user = userDao.getUserByUserId(userId);
        if (user == null) {
            throw new ServiceException("用户不存在");
        }
        return user;
    }

    /**
     * 换绑手机号
     *
     * @param userName 手机号
     * @param userId   用户编号
     * @return
     */
    @Override
    public boolean changePhone(String userName, int userId) throws ServiceException {
        User user = userDao.getUserByUserId(userId);
        if (user == null) {
            throw new ServiceException("用户不存在");
        }
        trendService.updateInfo(userId, userName, user.getPwd(), userName, 1, user.getNickName(), user.getHeadPic(), user.getSex());
        return userDao.changePhone(userName, userId);
    }

    /**
     * 进行数据的统计
     */
    @Override
    public Map<String, Object> statistics() throws ServiceException {
        Map map = new HashedMap();
        //用户数量
        Map<String, Object> userCount = userDao.userCount();
        //商家数量
        Map<String, Object> map1 = bussinessDao.businessCount();
        //配送员数量
        Map<String, Object> map2 = deliveryClerkDao.deliveryCount();
        //总配送订单
        Map<String, Object> allDispatchingOrder = orderDao.allDispatchingOrder();
        //日配送订单
        Map<String, Object> dayDispatchingOrder = orderDao.dayDispatchingOrder();
        //月配送订单
        Map<String, Object> monthDispatchingOrder = orderDao.monthDispatchingOrder();
        //年配送订单
        Map<String, Object> yearDispatchingOrder = orderDao.yearDispatchingOrder();
        //订单总金额
        Map<String, Object> allOrderMoney = orderDao.allOrder(1);
        //当天订单金额
        Map<String, Object> dayOrderMoney = orderDao.allOrder(2);
        //当天退款订单金额
        Map<String, Object> dayReturnMoney = orderDao.allOrder(3);
        //总退款订单金额
        Map<String, Object> allReturnMoney = orderDao.allOrder(4);
        //当日待支付订单金额
        Map<String, Object> pendingPayment = orderDao.allOrder(5);
        //待支付订单金额
        Map<String, Object> allPayment = orderDao.allOrder(6);
        //总成交订单
        Map<String, Object> allDealOrder = orderDao.allDealOrder(1);
        //日成交订单
        Map<String, Object> dayDealOrder = orderDao.allDealOrder(2);
        //月成交订单
        Map<String, Object> monthDealOrder = orderDao.allDealOrder(3);
        //年成交订单
        Map<String, Object> yearDealOrder = orderDao.allDealOrder(4);

        map.put("userCount", userCount.get("userCount"));
        map.put("businessCount", map1.get("businessCount"));
        map.put("deliveryCount", map2.get("deliveryCount"));
        map.put("allDispatchingOrder", allDispatchingOrder.get("allDispatchingOrder"));
        map.put("dayDispatchingOrder", dayDispatchingOrder.get("dayDispatchingOrder"));
        map.put("monthDispatchingOrder", monthDispatchingOrder.get("monthDispatchingOrder"));
        map.put("yearDispatchingOrder", yearDispatchingOrder.get("yearDispatchingOrder"));
        map.put("dayReturnMoney", dayReturnMoney.get("dayReturnMoney"));
        map.put("allReturnMoney", allReturnMoney.get("allReturnMoney"));
        map.put("allMoney", pendingPayment.get("allMoney"));
        map.put("allPendingMoney", allPayment.get("allPendingMoney"));
        map.put("sumMoney", allOrderMoney.get("sumMoney"));
        map.put("daySumMoney", dayOrderMoney.get("daySumMoney"));
        map.put("allDealOrder", allDealOrder.get("allDealOrder"));
        map.put("dayDealOrder", dayDealOrder.get("dayDealOrder"));
        map.put("monthDealOrder", monthDealOrder.get("monthDealOrder"));
        map.put("yearDealOrder", yearDealOrder.get("yearDealOrder"));
        return map;
    }

    @Override
    public Map<String, Object> getUserInfoByTrendsUserId(int userId) {
        return userDao.getUserInfoByTrendsUserId(userId);
    }

    @Override
    public boolean installBackGroundImage(Integer userId, String backGroundImage) {
        return userDao.updatebackgroundImage(backGroundImage, userId);
    }

    @Override
    public void updateUser(User user) {
        userDao.update(user);
    }

    /**
     * 功能描述:
     * 用户实名认证
     *
     * @param userId         用户编号
     * @param cardId         身份证号
     * @param cardName       身份证上的姓名
     * @param handheldPhotos 手持身份证照片
     * @param fontCard       身份证正面
     * @param reverseCard    身份证反面
     * @return:
     * @auther: wsl
     * @date: 2018/11/29 15:52
     */
    @Override
    public boolean certification(int userId, String cardId, String cardName, String handheldPhotos, String fontCard, String reverseCard) {
        return userDao.certification(userId, cardId, cardName, handheldPhotos, fontCard, reverseCard);
    }

    @Override
    public Map<String, Object> checkIsCertification(int userId) throws ServiceException {
        Map map = new HashMap(1);
        User user = userDao.getEntityById(userId);
        if (user == null) {
            throw new ServiceException("用户信息不存在！");
        } else {
            map.put("isCertification", user.getIsCertification());
            map.put("isCertificate", user.getIsCertificate());

        }
        return map;
    }

    @Override
    public boolean pass(Integer id, Integer type) {
        User user = userDao.getUserByUserId(id);
        if (type == 1) {
            SMSUtils.sendMsg(user.getAccount(), SMSConstants.certificationPass);
        } else {
            SMSUtils.sendMsg(user.getAccount(), SMSConstants.certificationRegect);
        }
        return userDao.updateIsCertification(id, type);
    }

    /**
     * 功能描述:
     * 查询用户的关联商家
     *
     * @param id       用户编号
     * @param nowPage  当前页
     * @param pageSize 每页条数
     * @return:
     * @auther: wsl
     * @date: 2019/1/12 10:04
     */
    @Override
    public Page queryCompanyList(Integer id, int nowPage, int pageSize) {
        return userDao.queryCompanyList(id, nowPage, pageSize);
    }

    @Override
    public Page queryCompanyOrderList(Integer id, int nowPage, int pageSize) {
        return rebateDao.queryCompanyOrderList(id, nowPage, pageSize);
    }

    @Override
    public void updateInviteAccount(int userId, String phone) {
        userDao.updateInviteAccount(userId,phone);
    }
}
